package com.sensetime.bi.senselink.server.entity;

import com.sensetime.bi.senselink.server.constant.Constant;
import com.sensetime.bi.senselink.server.util.StringUtils;
import io.netty.handler.codec.rtsp.RtspHeaderNames;
import lombok.Getter;
import lombok.Setter;
import lombok.extern.slf4j.Slf4j;

import java.io.UnsupportedEncodingException;
import java.util.Base64;

/**
 * Rtsp 请求消息体 （充血模型）
 */
@Slf4j
@Setter
@Getter
public class RtspRequestMsg {
    private String[] lines;
    private String method;

    private String URL;
    private String streamId;

    private String version;

    private String CSEQ;

    private String transport;
    private String session;
    private String range;
    private String protocol;

    private String ipAddr = "";
    private Integer port = 554;

    // 解析出来的真正的媒体源地址 rtsp://10.4.10.135:9554/test.mp4
    private String sourceUrl;
    private String userName;
    private String password;

    int contentLength;

    /**
     * 构造并解析
     * @param request 请求消息
     */
    public RtspRequestMsg(String request) {
        lines = StringUtils.getRawLines(request);

        int idx = 0;
        for (String line : lines) {
            if (idx++ == 0) {
                parseFirstLine(line);
            } else {
                String str = line.trim().toUpperCase();
                if (str.startsWith("CSEQ")) {
                    // Cseq
                    String[] tks = StringUtils.getTokens(line, ":");
                    this.CSEQ = tks[1].trim();
                    break;
                } else if (str.startsWith(RtspHeaderNames.CONTENT_LENGTH.toUpperCase().toString())) {
                    // Content-Length: 255
                    String[] tks = StringUtils.getTokens(line, ":");
                    this.contentLength = Integer.parseInt(tks[1].trim());
                }
            }
        }
    }

    /**
     * RTSP Request 报文 首行解析
     * 格式： METHOD URL [VERSION]
     * 示例： DESCRIBE rtsp://127.0.0.1:554 RTSP/1.0
     * @param line 行内容
     */
    private void parseFirstLine(String line) {
        String[] tokens = StringUtils.getTokens(line, Constant.RTSPTOKEN);
        int size = tokens.length;
        if (size < 2) {
            log.error("Rtsp request message error! first line:{}", line);
        }
        this.method = tokens[0].trim();
        setURL(tokens[1].trim());

        // 提取ip和port信息
        setIpAndPort(this.sourceUrl);
    }

    private void setIpAndPort(String sourceUrl) {
        if (sourceUrl == null || sourceUrl.length() < 1) {
            return;
        }
        // 获取真实的视频源地址 rtsp://10.4.10.135:9554/test.mp4
        String userPassPair = "";
        String ipPortPair = "";
        String other = "";
        int p2 = sourceUrl.lastIndexOf("@");
        int p1 = sourceUrl.indexOf("//");
        if (p2 !=-1) {
            userPassPair = sourceUrl.substring(p1 + 2, p2);
            ipPortPair = sourceUrl.substring(p2 + 1);
            int pos = StringUtils.getPos(ipPortPair, '/', 1);
            if (-1 != pos) {
                ipPortPair = ipPortPair.substring(0, pos);
                other = sourceUrl.substring(pos);
            }
        } else {
            int pos2 = StringUtils.getPos(sourceUrl, '/', 2);
            int pos3 = StringUtils.getPos(sourceUrl, '/', 3);
            log.debug("sourceUrl:{}, pos2：{}， pos3：{}", sourceUrl,pos2,pos3);
            if (pos3 == -1 && pos2 != -1) {
                ipPortPair = sourceUrl.substring(pos2);
            } else {
                ipPortPair = sourceUrl.substring(pos2, pos3 - 1);
                other = sourceUrl.substring(pos3 - 1);
            }

        }
        if (ipPortPair != "") {
            String[] tokens = StringUtils.getTokens(ipPortPair, ":");
            this.ipAddr = tokens[0].trim();
            if (tokens.length > 1) {
                this.port = Integer.parseInt(tokens[1].trim());
            }
        }

        if (userPassPair != "") {
            String[] tokens = StringUtils.getTokens(userPassPair, ":");
            this.userName = tokens[0].trim();
            if (tokens.length > 1) {
                this.password = tokens[1].trim();
            }
        }

        this.sourceUrl = "rtsp://" + this.ipAddr + ":" + this.port + other;

    }

    /**
     * rtsp://127.0.0.1:554/test.mp4
     * rtsp://10.4.10.177:8104/QWVTYUPKJHL--jbJ5xvUQe41UTUELM8VgeCsdLDL_Nh829IOlEjcB9oQ_h9jo1VqiqsXIFxfGlD8mOC3cXgA_dgUtgRiUUKrPEIaxPHSWXdM0C4OOqcHZAx8=/streamid=1
     * @param url 原始消息的URL
     */
    public void setURL(String url) {
        if (url.length() < 10) {
            return;
        }
        int pos4 = StringUtils.getPos(url, '/', 4);
        this.URL = pos4==-1?url : url.substring(0, pos4);
        if (pos4 != -1) {
            this.streamId = url.substring(pos4);
        }

        // 获取真实的视频源地址 rtsp://10.4.10.135:9554/test.mp4
        int pos3 = StringUtils.getPos(url, '/', 3);
        String sul = pos4 == -1 ? url.substring(pos3) : url.substring(pos3, pos4 - 1);
//        System.out.println("url=" + url + ", sul="+sul);
        this.sourceUrl = decodeSourceUrl(sul);
    }

    private String decodeSourceUrl(String encSourceUrl) {
        try {
            return new String(Base64.getDecoder().decode(encSourceUrl), "utf-8");
        } catch (UnsupportedEncodingException e) {
            log.error("cannot decode by BASE64! encSourceUrl:[%s]", encSourceUrl);
            return null;
        }
    }

    /**
     * RTSP 消息体
     */
    public void addContent(String bodyStr) {
        String[] contentLines = StringUtils.getRawLines(bodyStr);
        int newSize = this.lines.length + contentLines.length;
        String[] newlines = new String[newSize];
        int i = 0;
        for (String line : this.lines) {
            newlines[i++] = line;
        }

        for (String line : contentLines) {
            newlines[i++] = line;
        }

        this.lines = newlines;
    }

//    public static void main(String[] args) {
//        String msg = "SETUP rtsp://10.4.10.177:8104/QWVTYUPKJHL--jbJ5xvUQe41UTUELM8VgeCsdLDL_Nh829IOlEjcB9oQ_h9jo1VqiqsXIFxfGlD8mOC3cXgA_dgUtgRiUUKrPEIaxPHSWXdM0C4OOqcHZAx8=/streamid=1 RTSP/1.0";
//        String[] tokens = StringUtils.getTokens(msg, Constant.RTSPTOKEN);
//        for (String str: tokens) {
//            System.out.println("#" + str);
//        }
//        System.out.println(msg);
//
////        msg = "rtsp://10.4.10.177:8104/QWVTYUPKJHL--jbJ5xvUQe41UTUELM8VgeCsdLDL_Nh829IOlEjcB9oQ_h9jo1VqiqsXIFxfGlD8mOC3cXgA_dgUtgRiUUKrPEIaxPHSWXdM0C4OOqcHZAx8=/streamid=1";
//        msg = "rtsp://10.4.10.177:8104/";
////        tokens = StringUtils.getTokens(msg, "/");
////        for (String str: tokens) {
////            System.out.println("#" + str);
////        }
//
////        int pos3 = StringUtils.getPos(msg, '/', 3);
////        int pos4 = StringUtils.getPos(msg, '/', 4);
////        System.out.println(pos3);
////        System.out.println(pos4);
////        System.out.println(msg.substring(pos3, pos4-1));
////
////        pos4 = StringUtils.getPos(msg, '/', 4);
////        System.out.println(msg.substring(0, pos4-1));
//
//        String url = "cnRzcDovLzEwLjQuMTAuMTM1Ojk1NTQvdGVzdC5tcDQ=";
//        String s = null;
//        s = new String(Base64.getDecoder().decode(url));
//        System.out.println(s);
//
//        msg = "rtsp://guowen1:Goodsense@@10.4.189.70";
////        msg = "rtsp://10.4.189.70";
//        int p2 = msg.lastIndexOf("@");
//        int p1 = msg.indexOf("//");
//        System.out.println(p2);
//        if (p2 !=-1) {
//            String userPassPair = msg.substring(p1 + 2, p2);
//            System.out.println(userPassPair);
//
//            String ipPortPair = msg.substring(p2 + 1);
//            System.out.println(ipPortPair);
//            int pos = StringUtils.getPos(ipPortPair, '/', 1);
//            if (-1 != pos) {
//                ipPortPair = ipPortPair.substring(0, pos);
//            }
//            System.out.println(ipPortPair);
//        } else {
//
//        }
//
//    }


}
